﻿#if UNITY_EDITOR && PROFILING_CORE_API

using Unity.Profiling;
using Unity.Profiling.Editor;

namespace Devil
{

    [ProfilerModuleMetadata("Parallel Commands")]
    public class ParallelProfilerModule : ProfilerModule
    {
        public ParallelProfilerModule()
            : base(chartCounters: new ProfilerCounterDescriptor[] {
            new ProfilerCounterDescriptor("Schedule Commands", ProfilerCategory.Scripts),
            new ProfilerCounterDescriptor("Main Commands & Loopers", ProfilerCategory.Scripts),
            new ProfilerCounterDescriptor("Sub Commands & Loopers", ProfilerCategory.Scripts),
            },
                defaultChartType: ProfilerModuleChartType.Line,
                autoEnabledCategoryNames: new string[] { ProfilerCategory.Scripts.Name })
        {
        }
    }

    internal static class ParallelProfiler
    {
        const ProfilerCounterOptions COUNTER_OPTION = ProfilerCounterOptions.FlushOnEndOfFrame | ProfilerCounterOptions.ResetToZeroOnFlush;

        internal static readonly ProfilerCounterValue<int> ScheduleCommandsCount =
            new ProfilerCounterValue<int>(
                ProfilerCategory.Scripts,
                "Schedule Commands",
                ProfilerMarkerDataUnit.Count,
                COUNTER_OPTION);

        internal static readonly ProfilerCounterValue<int> MainCommandsCount =
            new ProfilerCounterValue<int>(
                ProfilerCategory.Scripts,
                "Main Commands & Loopers",
                ProfilerMarkerDataUnit.Count,
                COUNTER_OPTION);


        internal static readonly ProfilerCounterValue<int> SubCommandsCount =
            new ProfilerCounterValue<int>(
                ProfilerCategory.Scripts,
                "Sub Commands & Loopers",
                ProfilerMarkerDataUnit.Count,
                COUNTER_OPTION);
    }

    public partial class ParallelDispatcher
    {
        void CountSubCommands()
        {
            int num = mSubCmdQueue.Count;
            for (int i = mActiveWorkers - 1; i >= 0; i--)
            {
                num += mWorkers[i].ActiveCount;
            }
            for (int i = mLoopers.Length - 1; i >= 0; i--)
            {
                num += mLoopers[i].ActiveCount;
            }
            ParallelProfiler.SubCommandsCount.Value = num;
        }

        void CountMainCommands()
        {
            ParallelProfiler.MainCommandsCount.Value = mMainThreadWorker.ActiveCount + mMainCmdQueue.Count;
        }

        void CountScheduleCommands()
        {
            ParallelProfiler.ScheduleCommandsCount.Value = mCommands.Count;
        }
    }
}
#endif